// -*- coding: utf-8 -*-
#include "filecomparator.h"
#include <QFileInfo>
#include <QDir>

FileComparator::FileComparator(QObject *parent) : QObject(parent), m_leftTopLevelPackage(""), m_rightTopLevelPackage("")
{
}

void FileComparator::setLeftTopLevelPackage(const QString &packageName)
{
    m_leftTopLevelPackage = packageName;
}

void FileComparator::setRightTopLevelPackage(const QString &packageName)
{
    m_rightTopLevelPackage = packageName;
}

bool FileComparator::compareFiles(const QString &leftFilePath, const QString &rightFilePath)
{
    QFile leftFile(leftFilePath);
    QFile rightFile(rightFilePath);
    
    if (!leftFile.open(QIODevice::ReadOnly | QIODevice::Text) || 
        !rightFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return false; // 无法打开文件，认为不同
    }
    
    QString leftContent, rightContent;
    
    // 根据文件扩展名决定是否需要特殊处理
    QString leftExt = QFileInfo(leftFilePath).suffix().toLower();
    QString rightExt = QFileInfo(rightFilePath).suffix().toLower();
    
    if ((leftExt == "java" || leftExt == "kt") && (rightExt == "java" || rightExt == "kt")) {
        // 特殊处理Java/Kt文件，分别使用左右两侧的最上层包名
        leftContent = preprocessJavaKtFile(leftFilePath, true);  // 左侧文件
        rightContent = preprocessJavaKtFile(rightFilePath, false);  // 右侧文件
    } else {
        // 普通文件直接读取内容
        QTextStream leftStream(&leftFile);
        QTextStream rightStream(&rightFile);
        leftContent = leftStream.readAll();
        rightContent = rightStream.readAll();
    }
    
    leftFile.close();
    rightFile.close();
    
    return compareTextContent(leftContent, rightContent);
}

QString FileComparator::preprocessJavaKtFile(const QString &filePath, bool isLeftFile)
{
    QFile file(filePath);
    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        return "";
    }
    
    QTextStream stream(&file);
    QString content = stream.readAll();
    file.close();
    
    // 提取包名
    QString packageName;
    QRegularExpression packageRegex("^\\s*package\\s+([\\w.]+)\\s*;?\\s*$", QRegularExpression::MultilineOption);
    QRegularExpressionMatch match = packageRegex.match(content);
    if (match.hasMatch()) {
        packageName = match.captured(1);
    } else {
        // 如果文件中没有package声明，从文件路径解析包名
        packageName = extractPackageFromPath(filePath);
    }
    
    // 移除包声明行
    content = content.replace(packageRegex, "");
    
    // 忽略包下的import语句
    // 根据文件是左侧还是右侧，使用相应的最上层包名
    QString importPackage;
    if (isLeftFile) {
        importPackage = m_leftTopLevelPackage.isEmpty() ? packageName : m_leftTopLevelPackage;
    } else {
        importPackage = m_rightTopLevelPackage.isEmpty() ? packageName : m_rightTopLevelPackage;
    }
    
    if (!importPackage.isEmpty()) {
        // 创建匹配该包下所有import的正则表达式
        QString importRegexPattern = "^\\s*import\\s+" + QRegularExpression::escape(importPackage) + "\\.[\\w.]+\\s*;?\\s*$";
        QRegularExpression importRegex(importRegexPattern, QRegularExpression::MultilineOption);
        content = content.replace(importRegex, "");
    }
    
    return content;
}

QString FileComparator::extractPackageFromPath(const QString &filePath)
{
    // 从文件路径向上找到java或kotlin目录，然后构建包名
    QFileInfo fileInfo(filePath);
    QStringList pathParts;
    
    QDir currentDir = fileInfo.absoluteDir();
    QString currentDirName = currentDir.dirName();
    
    // 向上遍历直到找到java或kotlin目录
    while (!currentDir.isRoot() && currentDirName != "java" && currentDirName != "kotlin") {
        pathParts.prepend(currentDirName);
        currentDir.cdUp();
        currentDirName = currentDir.dirName();
    }
    
    // 如果找到java或kotlin目录，构建包名
    if (currentDirName == "java" || currentDirName == "kotlin") {
        return pathParts.join(".");
    }
    
    return "";
}

bool FileComparator::compareTextContent(const QString &leftContent, const QString &rightContent)
{
    // 移除空白字符进行比较，忽略格式差异
    auto removeWhitespace = [](const QString &text) {
        QString result = text;
        result = result.replace(QRegularExpression("\\s+"), " ");
        result = result.trimmed();
        return result;
    };
    
    QString cleanedLeft = removeWhitespace(leftContent);
    QString cleanedRight = removeWhitespace(rightContent);
    
    return cleanedLeft != cleanedRight;
}

QList<QPair<int, QString>> FileComparator::getDifferences(const QString &leftContent, const QString &rightContent)
{
    QList<QPair<int, QString>> differences;
    QStringList leftLines = leftContent.split("\n");
    QStringList rightLines = rightContent.split("\n");
    
    int maxLines = qMax(leftLines.size(), rightLines.size());
    
    for (int i = 0; i < maxLines; i++) {
        QString leftLine = (i < leftLines.size()) ? leftLines[i] : "";
        QString rightLine = (i < rightLines.size()) ? rightLines[i] : "";
        
        if (leftLine != rightLine) {
            differences.append(qMakePair(i, leftLine + " | " + rightLine));
        }
    }
    
    return differences;
}